package com.guiwu.config;

import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理器
 * 处理应用中的异常并提供友好的错误页面
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理一般异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ModelAndView handleException(HttpServletRequest request, Exception e) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.addObject("url", request.getRequestURL());
        mav.addObject("timestamp", System.currentTimeMillis());
        mav.setViewName("error/500");
        return mav;
    }

    /**
     * 处理404错误
     */
    @ExceptionHandler(org.springframework.web.servlet.NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ModelAndView handleNotFound(HttpServletRequest request, Exception e) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", request.getRequestURL());
        mav.addObject("timestamp", System.currentTimeMillis());
        mav.setViewName("error/404");
        return mav;
    }

    /**
     * 处理访问拒绝异常
     */
    @ExceptionHandler(org.springframework.security.access.AccessDeniedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public ModelAndView handleAccessDenied(HttpServletRequest request, Exception e) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", request.getRequestURL());
        mav.addObject("timestamp", System.currentTimeMillis());
        mav.setViewName("error/403");
        return mav;
    }

    /**
     * 处理用户认证异常 - 重定向到登录页面而不是显示错误页面
     */
    @ExceptionHandler(UsernameNotFoundException.class)
    public String handleUsernameNotFound(HttpServletRequest request, UsernameNotFoundException e) {
        // 记录日志但不显示错误页面，而是重定向到登录页面显示错误信息
        return "redirect:/login?error=true";
    }

    /**
     * 处理数据库连接异常
     */
    @ExceptionHandler({
        java.sql.SQLException.class,
        org.springframework.dao.DataAccessException.class,
        com.mysql.cj.jdbc.exceptions.CommunicationsException.class
    })
    @ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE)
    public ModelAndView handleDatabaseException(HttpServletRequest request, Exception e) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.addObject("url", request.getRequestURL());
        mav.addObject("timestamp", System.currentTimeMillis());
        mav.addObject("errorMessage", "数据库连接异常，请稍后重试或联系管理员");
        mav.setViewName("error");
        return mav;
    }
}
